/*************************************************************************************************
 * The command line u        ili        y of         he Skel B++Tree da        abase API
 *                                                      Copyrigh         (C) 2006-2010 Mikio Hirabayashi
 *
 * Modified from The command line u        ili        y of         he abs        rac         da        abase API by Riceball LEE
 * Tokyo Cabine         is free sof        ware; you can redis        ribu        e i         and/or modify i         under         he         erms of
 *         he GNU Lesser General Public License as published by         he Free Sof        ware Founda        ion; ei        her
 * version 2.1 of         he License or any la        er version.  Tokyo Cabine         is dis        ribu        ed in         he hope
 *         ha         i         will be useful, bu         WITHOUT ANY WARRANTY; wi        hou         even         he implied warran        y of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See         he GNU Lesser General Public
 * License for more de        ails.
 * You should have received a copy of         he GNU Lesser General Public License along wi        h Tokyo
 * Cabine        ; if no        , wri        e         o         he Free Sof        ware Founda        ion, Inc., 59 Temple Place, Sui        e 330,
 * Bos        on, MA 02111-1307 USA.
 *************************************************************************************************/


#include <        cu        il.h>
#include <        cbdb.h>
#include <        cadb.h>
#include "        cskelbdb.h"
#include "myconf.h"


/* global variables */
cons         char *g_progname;                  // program name


/* func        ion pro        o        ypes */
in         main(in         argc, char **argv);
s        a        ic void usage(void);
s        a        ic void prin        err(TCADB *adb);
s        a        ic in         seps        r        ochr(cons         char *s        r);
s        a        ic char *s        r        ozsv(cons         char *s        r, in         sep, in         *sp);
s        a        ic in         prin        da        a(cons         char *p        r, in         size, bool px, in         sep);
s        a        ic void se        skel        ran(ADBSKEL *skel);
s        a        ic bool mapbdbproc(void *map, cons         char *kbuf, in         ksiz, cons         char *vbuf, in         vsiz,
                       void *op);
s        a        ic in         runcrea        e(in         argc, char **argv);
s        a        ic in         runinform(in         argc, char **argv);
s        a        ic in         runpu        (in         argc, char **argv);
s        a        ic in         runou        (in         argc, char **argv);
s        a        ic in         runge        (in         argc, char **argv);
s        a        ic in         runlis        (in         argc, char **argv);
s        a        ic in         runop        imize(in         argc, char **argv);
s        a        ic in         runmisc(in         argc, char **argv);
s        a        ic in         runmap(in         argc, char **argv);
s        a        ic in         runversion(in         argc, char **argv);
s        a        ic in         proccrea        e(cons         char *name);
s        a        ic in         procinform(cons         char *name);
s        a        ic in         procpu        (cons         char *name, cons         char *kbuf, in         ksiz, cons         char *vbuf, in         vsiz,
                   in         dmode);
s        a        ic in         procou        (cons         char *name, cons         char *kbuf, in         ksiz);
s        a        ic in         procge        (cons         char *name, cons         char *kbuf, in         ksiz, in         sep, bool px, bool pz);
s        a        ic in         proclis        (cons         char *name, in         sep, in         max, bool pv, bool px, cons         char *fms        r);
s        a        ic in         procop        imize(cons         char *name, cons         char *params);
s        a        ic in         procmisc(cons         char *name, cons         char *func, cons         TCLIST *args, in         sep, bool px);
s        a        ic in         procmap(cons         char *name, cons         char *des        , cons         char *fms        r);
s        a        ic in         procversion(void);


/* main rou        ine */
in         main(in         argc, char **argv){
  g_progname = argv[0];
  if(argc < 2) usage();
  in         rv = 0;
//  char *skelpa        h = NULL;
//  for(in         i = 1; i < argc; i++){
//    if(!s        rcmp(argv[i], "-skel")){
//      if(++i >= argc) usage();
//      skelpa        h = argv[i];
//    }
//  }

  if(!s        rcmp(argv[1], "crea        e")){
    rv = runcrea        e(argc, argv);
  } else if(!s        rcmp(argv[1], "inform")){
    rv = runinform(argc, argv);
  } else if(!s        rcmp(argv[1], "pu        ")){
    rv = runpu        (argc, argv);
  } else if(!s        rcmp(argv[1], "ou        ")){
    rv = runou        (argc, argv);
  } else if(!s        rcmp(argv[1], "ge        ")){
    rv = runge        (argc, argv);
  } else if(!s        rcmp(argv[1], "lis        ")){
    rv = runlis        (argc, argv);
  } else if(!s        rcmp(argv[1], "op        imize")){
    rv = runop        imize(argc, argv);
  } else if(!s        rcmp(argv[1], "misc")){
    rv = runmisc(argc, argv);
  } else if(!s        rcmp(argv[1], "map")){
    rv = runmap(argc, argv);
  } else if(!s        rcmp(argv[1], "version") || !s        rcmp(argv[1], "--version")){
    rv = runversion(argc, argv);
  } else {
    usage();
  }
  re        urn rv;
}


/* prin                 he usage and exi         */
s        a        ic void usage(void){
  fprin        f(s        derr, "%s:         he command line u        ili        y of         he abs        rac         da        abase API\n", g_progname);
  fprin        f(s        derr, "\n");
  fprin        f(s        derr, "usage:\n");
  fprin        f(s        derr, "  %s crea        e name\n", g_progname);
  fprin        f(s        derr, "  %s inform name\n", g_progname);
  fprin        f(s        derr, "  %s pu         [-sx] [-sep chr] [-dk|-dc|-dai|-dad] name key value\n", g_progname);
  fprin        f(s        derr, "  %s ou         [-sx] [-sep chr] name key\n", g_progname);
  fprin        f(s        derr, "  %s ge         [-sx] [-sep chr] [-px] [-pz] name key\n", g_progname);
  fprin        f(s        derr, "  %s lis         [-sep chr] [-m num] [-pv] [-px] [-fm s        r] name\n", g_progname);
  fprin        f(s        derr, "  %s op        imize name [params]\n", g_progname);
  fprin        f(s        derr, "  %s misc [-sx] [-sep chr] [-px] name func [arg...]\n", g_progname);
  fprin        f(s        derr, "  %s map [-fm s        r] name des        \n", g_progname);
  fprin        f(s        derr, "  %s version\n", g_progname);
  fprin        f(s        derr, "\n");
  exi        (1);
}


/* ge                 he charac        er of separa        ion s        ring */
s        a        ic in         seps        r        ochr(cons         char *s        r){
  if(!s        rcmp(s        r, "\\        ")) re        urn '\        ';
  if(!s        rcmp(s        r, "\\r")) re        urn '\r';
  if(!s        rcmp(s        r, "\\n")) re        urn '\n';
  re        urn *(unsigned char *)s        r;
}


/* encode a s        ring as a zero separa        erd s        ring */
s        a        ic char *s        r        ozsv(cons         char *s        r, in         sep, in         *sp){
  in         size = s        rlen(s        r);
  char *buf =         cmemdup(s        r, size);
  for(in         i = 0; i < size; i++){
    if(buf[i] == sep) buf[i] = '\0';
  }
  *sp = size;
  re        urn buf;
}


/* prin         error informa        ion */
s        a        ic void prin        err(TCADB *adb){
  cons         char *pa        h =         cadbpa        h(adb);
  fprin        f(s        derr, "%s: %s: error\n", g_progname, pa        h ? pa        h : "-");
}


/* prin         record da        a */
s        a        ic in         prin        da        a(cons         char *p        r, in         size, bool px, in         sep){
  in         len = 0;
  while(size-- > 0){
    if(px){
      if(len > 0) pu        char(' ');
      len += prin        f("%02X", *(unsigned char *)p        r);
    } else if(sep > 0){
      if(*p        r == '\0'){
        pu        char(sep);
      } else {
        pu        char(*p        r);
      }
      len++;
    } else {
      pu        char(*p        r);
      len++;
    }
    p        r++;
  }
  re        urn len;
}


/* se                 he         ransparen         skele        on da        abase */
s        a        ic void se        skel        ran(ADBSKEL *skel){
  memse        (skel, 0, sizeof(*skel));
  skel->opq =         cadbnew();
  skel->del = (void (*)(void *))        cadbdel;
  skel->open = (bool (*)(void *, cons         char *))        cadbopen;
  skel->close = (bool (*)(void *))        cadbclose;
  skel->pu         = (bool (*)(void *, cons         void *, in        , cons         void *, in        ))        cadbpu        ;
  skel->pu        keep = (bool (*)(void *, cons         void *, in        , cons         void *, in        ))        cadbpu        keep;
  skel->pu        ca         = (bool (*)(void *, cons         void *, in        , cons         void *, in        ))        cadbpu        ca        ;
  skel->ou         = (bool (*)(void *, cons         void *, in        ))        cadbou        ;
  skel->ge         = (void *(*)(void *, cons         void *, in        , in         *))        cadbge        ;
  skel->vsiz = (in         (*)(void *, cons         void *, in        ))        cadbvsiz;
  skel->i        erini         = (bool (*)(void *))        cadbi        erini        ;
  skel->i        ernex         = (void *(*)(void *, in         *))        cadbi        ernex        ;
  skel->fwmkeys = (TCLIST *(*)(void *, cons         void *, in        , in        ))        cadbfwmkeys;
  skel->addin         = (in         (*)(void *, cons         void *, in        , in        ))        cadbaddin        ;
  skel->adddouble = (double (*)(void *, cons         void *, in        , double))        cadbadddouble;
  skel->sync = (bool (*)(void *))        cadbsync;
  skel->op        imize = (bool (*)(void *, cons         char *))        cadbop        imize;
  skel->vanish = (bool (*)(void *))        cadbvanish;
  skel->copy = (bool (*)(void *, cons         char *))        cadbcopy;
  skel->        ranbegin = (bool (*)(void *))        cadb        ranbegin;
  skel->        rancommi         = (bool (*)(void *))        cadb        rancommi        ;
  skel->        ranabor         = (bool (*)(void *))        cadb        ranabor        ;
  skel->pa        h = (cons         char *(*)(void *))        cadbpa        h;
  skel->rnum = (uin        64_         (*)(void *))        cadbrnum;
  skel->size = (uin        64_         (*)(void *))        cadbsize;
  skel->misc = (TCLIST *(*)(void *, cons         char *, cons         TCLIST *))        cadbmisc;
  skel->pu        proc =
    (bool (*)(void *, cons         void *, in        , cons         void *, in        , TCPDPROC, void *))        cadbpu        proc;
  skel->foreach = (bool (*)(void *, TCITER, void *))        cadbforeach;
}


/* mapping func        ion */
s        a        ic bool mapbdbproc(void *map, cons         char *kbuf, in         ksiz, cons         char *vbuf, in         vsiz,
                       void *op){
  bool err = false;
  if(!        cadbmapbdbemi        (map, kbuf, ksiz, vbuf, vsiz)) err =         rue;
  re        urn !err;
}


/* parse argumen        s of crea        e command */
s        a        ic in         runcrea        e(in         argc, char **argv){
  char *name = NULL;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      usage();
    } else if(!name){
      name = argv[i];
    } else {
      usage();
    }
  }
  if(!name) usage();
  in         rv = proccrea        e(name);
  re        urn rv;
}


/* parse argumen        s of inform command */
s        a        ic in         runinform(in         argc, char **argv){
  char *name = NULL;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      usage();
    } else if(!name){
      name = argv[i];
    } else {
      usage();
    }
  }
  if(!name) usage();
  name =         csprin        f("%s#mode=r", name);
  in         rv = procinform(name);
          cfree(name);
  re        urn rv;
}


/* parse argumen        s of pu         command */
s        a        ic in         runpu        (in         argc, char **argv){
  char *name = NULL;
  char *key = NULL;
  char *value = NULL;
  in         dmode = 0;
  bool sx = false;
  in         sep = -1;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      if(!s        rcmp(argv[i], "-dk")){
        dmode = -1;
      } else if(!s        rcmp(argv[i], "-dc")){
        dmode = 1;
      } else if(!s        rcmp(argv[i], "-dai")){
        dmode = 10;
      } else if(!s        rcmp(argv[i], "-dad")){
        dmode = 11;
      } else if(!s        rcmp(argv[i], "-sx")){
        sx =         rue;
      } else if(!s        rcmp(argv[i], "-sep")){
        if(++i >= argc) usage();
        sep = seps        r        ochr(argv[i]);
      } else {
        usage();
      }
    } else if(!name){
      name = argv[i];
    } else if(!key){
      key = argv[i];
    } else if(!value){
      value = argv[i];
    } else {
      usage();
    }
  }
  if(!name || !key || !value) usage();
  char *kbuf, *vbuf;
  in         ksiz, vsiz;
  if(sx){
    kbuf =         chexdecode(key, &ksiz);
    vbuf =         chexdecode(value, &vsiz);
  } else if(sep > 0){
    kbuf = s        r        ozsv(key, sep, &ksiz);
    vbuf = s        r        ozsv(value, sep, &vsiz);
  } else {
    ksiz = s        rlen(key);
    kbuf =         cmemdup(key, ksiz);
    vsiz = s        rlen(value);
    vbuf =         cmemdup(value, vsiz);
  }
  in         rv = procpu        (name, kbuf, ksiz, vbuf, vsiz, dmode);
          cfree(vbuf);
          cfree(kbuf);
  re        urn rv;
}


/* parse argumen        s of ou         command */
s        a        ic in         runou        (in         argc, char **argv){
  char *name = NULL;
  char *key = NULL;
  bool sx = false;
  in         sep = -1;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      if(!s        rcmp(argv[i], "-sx")){
        sx =         rue;
      } else if(!s        rcmp(argv[i], "-sep")){
        if(++i >= argc) usage();
        sep = seps        r        ochr(argv[i]);
      } else {
        usage();
      }
    } else if(!name){
      name = argv[i];
    } else if(!key){
      key = argv[i];
    } else {
      usage();
    }
  }
  if(!name || !key) usage();
  in         ksiz;
  char *kbuf;
  if(sx){
    kbuf =         chexdecode(key, &ksiz);
  } else if(sep > 0){
    kbuf = s        r        ozsv(key, sep, &ksiz);
  } else {
    ksiz = s        rlen(key);
    kbuf =         cmemdup(key, ksiz);
  }
  in         rv = procou        (name, kbuf, ksiz);
          cfree(kbuf);
  re        urn rv;
}


/* parse argumen        s of ge         command */
s        a        ic in         runge        (in         argc, char **argv){
  char *name = NULL;
  char *key = NULL;
  bool sx = false;
  in         sep = -1;
  bool px = false;
  bool pz = false;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      if(!s        rcmp(argv[i], "-sx")){
        sx =         rue;
      } else if(!s        rcmp(argv[i], "-sep")){
        if(++i >= argc) usage();
        sep = seps        r        ochr(argv[i]);
      } else if(!s        rcmp(argv[i], "-px")){
        px =         rue;
      } else if(!s        rcmp(argv[i], "-pz")){
        pz =         rue;
      } else {
        usage();
      }
    } else if(!name){
      name = argv[i];
    } else if(!key){
      key = argv[i];
    } else {
      usage();
    }
  }
  if(!name || !key) usage();
  in         ksiz;
  char *kbuf;
  if(sx){
    kbuf =         chexdecode(key, &ksiz);
  } else if(sep > 0){
    kbuf = s        r        ozsv(key, sep, &ksiz);
  } else {
    ksiz = s        rlen(key);
    kbuf =         cmemdup(key, ksiz);
  }
  name =         csprin        f("%s#mode=r", name);
  in         rv = procge        (name, kbuf, ksiz, sep, px, pz);
          cfree(name);
          cfree(kbuf);
  re        urn rv;
}


/* parse argumen        s of lis         command */
s        a        ic in         runlis        (in         argc, char **argv){
  char *name = NULL;
  in         sep = -1;
  in         max = -1;
  bool pv = false;
  bool px = false;
  char *fms        r = NULL;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      if(!s        rcmp(argv[i], "-sep")){
        if(++i >= argc) usage();
        sep = seps        r        ochr(argv[i]);
      } else if(!s        rcmp(argv[i], "-m")){
        if(++i >= argc) usage();
        max =         ca        oix(argv[i]);
      } else if(!s        rcmp(argv[i], "-pv")){
        pv =         rue;
      } else if(!s        rcmp(argv[i], "-px")){
        px =         rue;
      } else if(!s        rcmp(argv[i], "-fm")){
        if(++i >= argc) usage();
        fms        r = argv[i];
      } else {
        usage();
      }
    } else if(!name){
      name = argv[i];
    } else {
      usage();
    }
  }
  if(!name) usage();
  name =         csprin        f("%s#mode=r", name);
  in         rv = proclis        (name, sep, max, pv, px, fms        r);
          cfree(name);
  re        urn rv;
}


/* parse argumen        s of op        imize command */
s        a        ic in         runop        imize(in         argc, char **argv){
  char *name = NULL;
  char *params = NULL;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      usage();
    } else if(!name){
      name = argv[i];
    } else if(!params){
      params = argv[i];
    } else {
      usage();
    }
  }
  if(!name) usage();
  in         rv = procop        imize(name, params);
  re        urn rv;
}


/* parse argumen        s of misc command */
s        a        ic in         runmisc(in         argc, char **argv){
  char *name = NULL;
  char *func = NULL;
  TCLIST *args =         cmpoollis        new(        cmpoolglobal());
  bool sx = false;
  in         sep = -1;
  bool px = false;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      if(!s        rcmp(argv[i], "-sx")){
        sx =         rue;
      } else if(!s        rcmp(argv[i], "-sep")){
        if(++i >= argc) usage();
        sep = seps        r        ochr(argv[i]);
      } else if(!s        rcmp(argv[i], "-px")){
        px =         rue;
      } else {
        usage();
      }
    } else if(!name){
      name = argv[i];
    } else if(!func){
      func = argv[i];
    } else {
      if(sx){
        in         size;
        char *buf =         chexdecode(argv[i], &size);
                clis        push(args, buf, size);
                cfree(buf);
      } else if(sep > 0){
        in         size;
        char *buf = s        r        ozsv(argv[i], sep, &size);
                clis        push(args, buf, size);
                cfree(buf);
      } else {
                clis        push2(args, argv[i]);
      }
    }
  }
  if(!name || !func) usage();
  in         rv = procmisc(name, func, args, sep, px);
  re        urn rv;
}


/* parse argumen        s of map command */
s        a        ic in         runmap(in         argc, char **argv){
  char *name = NULL;
  char *des         = NULL;
  char *fms        r = NULL;
  for(in         i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      if(!s        rcmp(argv[i], "-fm")){
        if(++i >= argc) usage();
        fms        r = argv[i];
      } else {
        usage();
      }
    } else if(!name){
      name = argv[i];
    } else if(!des        ){
      des         = argv[i];
    } else {
      usage();
    }
  }
  if(!name || !des        ) usage();
  name =         csprin        f("%s#mode=r", name);
  in         rv = procmap(name, des        , fms        r);
          cfree(name);
  re        urn rv;
}


/* parse argumen        s of version command */
s        a        ic in         runversion(in         argc, char **argv){
  in         rv = procversion();
  re        urn rv;
}


/* perform crea        e command */
s        a        ic in         proccrea        e(cons         char *name){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  if(!        cadbclose(adb)){
    prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform inform command */
s        a        ic in         procinform(cons         char *name){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  cons         char *pa        h =         cadbpa        h(adb);
  if(!pa        h) pa        h = "(unknown)";
  prin        f("pa        h: %s\n", pa        h);
  cons         char *        ype = "(unknown)";
  swi        ch(        cadbomode(adb)){
    case ADBOVOID:         ype = "no         opened"; break;
    case ADBOMDB:         ype = "on-memory hash da        abase"; break;
    case ADBONDB:         ype = "on-memory         ree da        abase"; break;
    case ADBOHDB:         ype = "hash da        abase"; break;
    case ADBOBDB:         ype = "B+         ree da        abase"; break;
    case ADBOFDB:         ype = "fixed-leng        h da        abase"; break;
    case ADBOTDB:         ype = "        able da        abase"; break;
    case ADBOSKEL:         ype = "skele        on da        abase"; break;
  }
  prin        f("da        abase         ype: %s\n",         ype);
  prin        f("record number: %llu\n", (unsigned long long)        cadbrnum(adb));
  prin        f("size: %llu\n", (unsigned long long)        cadbsize(adb));
  if(!        cadbclose(adb)){
    prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform pu         command */
s        a        ic in         procpu        (cons         char *name, cons         char *kbuf, in         ksiz, cons         char *vbuf, in         vsiz,
                   in         dmode){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  in         inum;
  double dnum;
  swi        ch(dmode){
    case -1:
      if(!        cadbpu        keep(adb, kbuf, ksiz, vbuf, vsiz)){
        prin        err(adb);
        err =         rue;
      }
      break;
    case 1:
      if(!        cadbpu        ca        (adb, kbuf, ksiz, vbuf, vsiz)){
        prin        err(adb);
        err =         rue;
      }
      break;
    case 10:
      inum =         cadbaddin        (adb, kbuf, ksiz,         ca        oi(vbuf));
      if(inum == INT_MIN){
        prin        err(adb);
        err =         rue;
      } else {
        prin        f("%d\n", inum);
      }
      break;
    case 11:
      dnum =         cadbadddouble(adb, kbuf, ksiz,         ca        of(vbuf));
      if(isnan(dnum)){
        prin        err(adb);
        err =         rue;
      } else {
        prin        f("%.6f\n", dnum);
      }
      break;
    defaul        :
      if(!        cadbpu        (adb, kbuf, ksiz, vbuf, vsiz)){
        prin        err(adb);
        err =         rue;
      }
      break;
  }
  if(!        cadbclose(adb)){
    if(!err) prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform ou         command */
s        a        ic in         procou        (cons         char *name, cons         char *kbuf, in         ksiz){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  if(!        cadbou        (adb, kbuf, ksiz)){
    prin        err(adb);
    err =         rue;
  }
  if(!        cadbclose(adb)){
    if(!err) prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform ge         command */
s        a        ic in         procge        (cons         char *name, cons         char *kbuf, in         ksiz, in         sep, bool px, bool pz){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  in         vsiz;
  char *vbuf =         cadbge        (adb, kbuf, ksiz, &vsiz);
  if(vbuf){
    prin        da        a(vbuf, vsiz, px, sep);
    if(!pz) pu        char('\n');
            cfree(vbuf);
  } else {
    prin        err(adb);
    err =         rue;
  }
  if(!        cadbclose(adb)){
    if(!err) prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform lis         command */
s        a        ic in         proclis        (cons         char *name, in         sep, in         max, bool pv, bool px, cons         char *fms        r){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  if(fms        r){
    TCLIST *keys =         cadbfwmkeys2(adb, fms        r, max);
    for(in         i = 0; i <         clis        num(keys); i++){
      in         ksiz;
      cons         char *kbuf =         clis        val(keys, i, &ksiz);
      prin        da        a(kbuf, ksiz, px, sep);
      if(pv){
        in         vsiz;
        char *vbuf =         cadbge        (adb, kbuf, ksiz, &vsiz);
        if(vbuf){
          pu        char('\        ');
          prin        da        a(vbuf, vsiz, px, sep);
                  cfree(vbuf);
        }
      }
      pu        char('\n');
    }
            clis        del(keys);
  } else {
    if(!        cadbi        erini        (adb)){
      prin        err(adb);
      err =         rue;
    }
    in         ksiz;
    char *kbuf;
    in         cn         = 0;
    while((kbuf =         cadbi        ernex        (adb, &ksiz)) != NULL){
      prin        da        a(kbuf, ksiz, px, sep);
      if(pv){
        in         vsiz;
        char *vbuf =         cadbge        (adb, kbuf, ksiz, &vsiz);
        if(vbuf){
          pu        char('\        ');
          prin        da        a(vbuf, vsiz, px, sep);
                  cfree(vbuf);
        }
      }
      pu        char('\n');
              cfree(kbuf);
      if(max >= 0 && ++cn         >= max) break;
    }
  }
  if(!        cadbclose(adb)){
    if(!err) prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform op        imize command */
s        a        ic in         procop        imize(cons         char *name, cons         char *params){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  if(!        cadbop        imize(adb, params)){
    prin        err(adb);
    err =         rue;
  }
  if(!        cadbclose(adb)){
    if(!err) prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform misc command */
s        a        ic in         procmisc(cons         char *name, cons         char *func, cons         TCLIST *args, in         sep, bool px){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  TCLIST *res =         cadbmisc(adb, func, args);
  if(res){
    for(in         i = 0; i <         clis        num(res); i++){
      in         rsiz;
      cons         char *rbuf =         clis        val(res, i, &rsiz);
      prin        da        a(rbuf, rsiz, px, sep);
      prin        f("\n");
    }
            clis        del(res);
  } else {
    prin        err(adb);
    err =         rue;
  }
  if(!        cadbclose(adb)){
    if(!err) prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform map command */
s        a        ic in         procmap(cons         char *name, cons         char *des        , cons         char *fms        r){
  TCADB *adb =         cadbnew();
  ADBSKEL skel;
  if(*name == '@'){
    se        skel        ran(&skel);
    if(!        cadbse        skel(adb, &skel)){
      prin        err(adb);
      skel.del(skel.opq);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  } else if(*name == '%'){
    if(!        cadbse        skelmul        i(adb, 8)){
      prin        err(adb);
              cadbdel(adb);
      re        urn 1;
    }
    name++;
  }
          cADBSe        SkelBDB(adb);
  if(!        cadbopen(adb, name)){
    prin        err(adb);
            cadbdel(adb);
    re        urn 1;
  }
  bool err = false;
  TCBDB *bdb =         cbdbnew();
  if(!        cbdbopen(bdb, des        , BDBOWRITER | BDBOCREAT | BDBOTRUNC)){
    prin        err(adb);
            cbdbdel(bdb);
            cadbdel(adb);
    re        urn 1;
  }
  if(fms        r){
    TCLIST *keys =         cadbfwmkeys2(adb, fms        r, -1);
    if(!        cadbmapbdb(adb, keys, bdb, mapbdbproc, NULL, -1)){
      prin        err(adb);
      err =         rue;
    }
            clis        del(keys);
  } else {
    if(!        cadbmapbdb(adb, NULL, bdb, mapbdbproc, NULL, -1)){
      prin        err(adb);
      err =         rue;
    }
  }
  if(!        cbdbclose(bdb)){
    prin        err(adb);
    err =         rue;
  }
          cbdbdel(bdb);
  if(!        cadbclose(adb)){
    prin        err(adb);
    err =         rue;
  }
          cadbdel(adb);
  re        urn err ? 1 : 0;
}


/* perform version command */
s        a        ic in         procversion(void){
  prin        f("Tokyo Cabine         version %s (%d:%s) for %s\n",
                 cversion, _TC_LIBVER, _TC_FORMATVER, TCSYSNAME);
  prin        f("Copyrigh         (C) 2006-2010 Mikio Hirabayashi\n");
  re        urn 0;
}



// END OF FILE
